package cn.xshi.job.client;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
 * @Desc 客户端连接
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Component
@Slf4j
public class NettyClient {

    private EventLoopGroup group = new NioEventLoopGroup();

    @Value("${jehc.job.host:}")
    private String host;

    @Value("${jehc.job.port:}")
    private Integer port;

    @Value("${jehc.job.clientId:}")
    private String clientId;//客户端id（每个服务对应一个客户端唯一id）

    @Value("${jehc.job.clientGroupId:}")
    private String clientGroupId;//组Id（可以存多个服务共享一个组Id）

    private SocketChannel socketChannel;

    @Resource
    private NettyClient nettyClient;

    /**
     * 发送消息
     */
    public void send(String message) {
        socketChannel.writeAndFlush(message);
    }

    /**
     *
     */
    @PostConstruct
    public void start() {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                 .channel(NioSocketChannel.class)
                 .remoteAddress(host, port)
                 .option(ChannelOption.SO_KEEPALIVE, true)
                 .option(ChannelOption.TCP_NODELAY, true)
                 .handler(new NettyClientInitializer(nettyClient,clientGroupId,clientId));
        ChannelFuture future = bootstrap.connect();
        //客户端断线重连逻辑
        future.addListener((ChannelFutureListener) future1 -> {
            if (future1.isSuccess()) {
                log.info("连接Netty服务端成功");
            } else {
                log.info("连接失败，进行断线重连");
                future1.channel().eventLoop().schedule(() -> start(), 20, TimeUnit.SECONDS);
            }
        });
        socketChannel = (SocketChannel) future.channel();
        log.info("通道号："+socketChannel.id());
    }
}
